import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { TASK_STATUS, TASK_STATUS_MAPPING } from "./constants";

/**
 * 合并Tailwind CSS类名
 */
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

/**
 * 格式化日期
 */
export function formatDate(date: Date | string): string {
  const d = typeof date === 'string' ? new Date(date) : date;
  return d.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  });
}

/**
 * 格式化时间
 */
export function formatTime(date: Date | string): string {
  const d = typeof date === 'string' ? new Date(date) : date;
  return d.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
  });
}

/**
 * 格式化日期时间
 */
export function formatDateTime(date: Date | string): string {
  const d = typeof date === 'string' ? new Date(date) : date;
  return d.toLocaleString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

/**
 * 生成随机颜色
 */
export function getRandomColor(): string {
  return `#${Math.floor(Math.random() * 16777215).toString(16)}`;
}

/**
 * 截断文本
 */
export function truncateText(text: string, maxLength: number): string {
  if (text.length <= maxLength) return text;
  return text.slice(0, maxLength) + '...';
}

/**
 * 任务状态映射函数 - 处理大小写不一致的问题
 * 将任何格式的状态值标准化为小写中划线格式
 */
export function normalizeTaskStatus(status: string): string {
  // 如果是空值，返回默认状态
  if (!status) return TASK_STATUS.TODO;
  
  // 转换为小写
  const lowercaseStatus = status.toLowerCase();
  
  // 处理常见的大写格式
  switch (lowercaseStatus) {
    case 'todo':
    case 'to-do':
    case 'to_do':
      return TASK_STATUS.TODO;
    
    case 'in_progress':
    case 'inprogress':
    case 'in-progress':
    case 'in progress':
      return TASK_STATUS.IN_PROGRESS;
    
    case 'review':
    case 'in_review':
    case 'in-review':
    case 'reviewing':
      return TASK_STATUS.REVIEW;
    
    case 'done':
    case 'completed':
    case 'complete':
    case 'finished':
      return TASK_STATUS.DONE;
    
    default:
      // 如果没有匹配到任何已知状态，返回原值
      return lowercaseStatus;
  }
}

/**
 * 任务状态映射函数 - 处理API和UI之间的格式转换
 * 将小写中划线格式转换为大写下划线格式(用于API请求)
 * 
 * 使用TASK_STATUS_MAPPING常量确保与Prisma模型一致
 */
export function taskStatusToApiFormat(status: string): string {
  // 先标准化状态
  const normalizedStatus = normalizeTaskStatus(status);
  
  // 根据UI格式查找对应的Prisma格式
  for (const [prismaStatus, uiStatus] of Object.entries(TASK_STATUS_MAPPING)) {
    if (uiStatus === normalizedStatus) {
      return prismaStatus;
    }
  }
  
  // 如果没有找到匹配项，则按照旧逻辑处理
  switch (normalizedStatus) {
    case TASK_STATUS.TODO:
      return 'TODO';
    case TASK_STATUS.IN_PROGRESS:
      return 'IN_PROGRESS';
    case TASK_STATUS.REVIEW:
      return 'REVIEW';
    case TASK_STATUS.DONE:
      return 'DONE';
    default:
      // 如果不是标准状态，转换为大写并替换中划线为下划线
      return normalizedStatus.toUpperCase().replace(/-/g, '_');
  }
}

/**
 * 任务状态映射函数 - 处理API和UI之间的格式转换
 * 将大写下划线格式转换为小写中划线格式(用于UI显示)
 * 
 * 使用TASK_STATUS_MAPPING常量确保与Prisma模型一致
 */
export function taskStatusFromApiFormat(status: string): string {
  // 如果是空值，返回默认状态
  if (!status) return TASK_STATUS.TODO;
  
  // 直接从映射中获取UI格式
  if (TASK_STATUS_MAPPING[status]) {
    return TASK_STATUS_MAPPING[status];
  }
  
  // 如果没有在映射中找到，按照旧逻辑处理
  const lowercaseStatus = status.toLowerCase();
  
  // 处理常见的API格式
  switch (lowercaseStatus) {
    case 'todo':
      return TASK_STATUS.TODO;
    case 'in_progress':
      return TASK_STATUS.IN_PROGRESS;
    case 'review':
      return TASK_STATUS.REVIEW;
    case 'done':
      return TASK_STATUS.DONE;
    default:
      // 如果不是标准状态，转换为小写并替换下划线为中划线
      return lowercaseStatus.replace(/_/g, '-');
  }
}

/**
 * 格式化相对时间
 */
export function formatRelativeTime(date: Date | string): string {
  const d = typeof date === 'string' ? new Date(date) : date;
  const now = new Date();
  const diffInSeconds = Math.floor((now.getTime() - d.getTime()) / 1000);
  
  if (diffInSeconds < 60) return '刚刚';
  if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}分钟前`;
  if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}小时前`;
  if (diffInSeconds < 2592000) return `${Math.floor(diffInSeconds / 86400)}天前`;
  
  return formatDate(d, { year: 'numeric', month: 'short', day: 'numeric' });
}

/**
 * 生成随机ID
 */
export function generateId(length: number = 8): string {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  
  return result;
}

/**
 * 深度合并对象
 */
export function deepMerge<T extends object = object>(target: T, source: Partial<T>): T {
  const output = { ...target };
  
  if (isObject(target) && isObject(source)) {
    Object.keys(source).forEach(key => {
      if (isObject(source[key as keyof typeof source])) {
        if (!(key in target)) {
          Object.assign(output, { [key]: source[key as keyof typeof source] });
        } else {
          output[key as keyof T] = deepMerge(
            target[key as keyof typeof target] as object,
            source[key as keyof typeof source] as object
          ) as any;
        }
      } else {
        Object.assign(output, { [key]: source[key as keyof typeof source] });
      }
    });
  }
  
  return output;
}

/**
 * 检查是否为对象
 */
function isObject(item: any): boolean {
  return item && typeof item === 'object' && !Array.isArray(item);
}

/**
 * 防抖函数
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: ReturnType<typeof setTimeout> | null = null;
  
  return function(...args: Parameters<T>) {
    const later = () => {
      timeout = null;
      func(...args);
    };
    
    if (timeout !== null) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(later, wait);
  };
}

/**
 * 节流函数
 */
export function throttle<T extends (...args: any[]) => any>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void {
  let inThrottle = false;
  
  return function(...args: Parameters<T>) {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => {
        inThrottle = false;
      }, limit);
    }
  };
} 